package org.flckphoto;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.*;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

import java.io.*;
import java.util.Vector;

/**
 * Customized Gallery for previewing images on the phone
 */
public class Gallery extends Activity{
	private static final String TAG = "Gallery";
	private static final int[] IMAGE_IDS = {R.id.galleryImage1, R.id.galleryImage2,
											R.id.galleryImage3, R.id.galleryImage4,
											R.id.galleryImage5, R.id.galleryImage6
											};
	private static final int PHOTO_REQUEST = 987654321;
	public static final int PICS_PER_PAGE = 6;
	private int currentPage;
	private int numPages;
	private Vector<String> pictures;
	private Page curPage = null;
	private Button next;
	private Button prev;
	private ProgressDialog pDia; 
	private boolean init;
	
	@Override
	public void onCreate(Bundle bundle) {
		super.onCreate(bundle);
		
		pictures = new Vector<String>();
		pDia = new ProgressDialog(Gallery.this);
		pDia.setCancelable(false);
		pDia.setMessage("Loading page...");
		pDia.setProgressStyle(ProgressDialog.STYLE_SPINNER);
		
		String DCIM = Settings.getDataPath();
		if(!DCIM.equals("")) {
			DCIM = DCIM.substring(0, DCIM.length() - 11); //take out FlickPhoto
			findPictures(DCIM);
			
			setContentView(R.layout.gallery);
			next = (Button) findViewById(R.id.galleryNextPage);
			prev = (Button) findViewById(R.id.galleryPrevPage);
			prev.setEnabled(false);
			
			next.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					nextPage();
				}
			});
			
			prev.setOnClickListener(new OnClickListener(){
				@Override
				public void onClick(View v) {
					previousPage();
				}
			});
			
			initPage();
		}
		else {
			Log.e(TAG, "SD Card not available for searching");
			finish();
		}
	}
	
	/*@Override
	public void onPause() {
		super.onPause();
		curPage.unloadPictures();
		init = false;
	}
	
	@Override
	public void onResume() {
		super.onResume();
		if(!onStart){
			initPage();
		}
		onStart = false;
	}
	
	@Override
	public void onStart() {
		super.onStart();
		initPage();
		onStart = true;
	}
	
	@Override
	public void onStop() {
		super.onStop();
		curPage.unloadPictures();
	}*/
	
	/**
	 * recursively searches the DCIM folder for pictures
	 */
	private void findPictures(String directory) {
		File dir = new File(directory);
		String[] children = dir.list();
		
		if(children != null) {
			for(String x : children) {
				if(x != null) {
					File file = new File(directory + "/" + x);
					if(file.isDirectory())
						findPictures(file.getAbsolutePath());
					else if(file.isFile() && file.getName().endsWith(".jpg"))
						pictures.add(directory + "/" + x);
				}
			}
		}
	}
	
	/**
	 * goes to the next page and transitions the pictures
	 */
	private void nextPage() {
		currentPage++;
		if(currentPage > numPages) {
			currentPage = numPages;
			next.setEnabled(false);
		}
		else if(!next.isEnabled()) {
			next.setEnabled(true);
		}
		else if(!prev.isEnabled()) {
			prev.setEnabled(true);
		}

		populatePage();
		initViews();
		displayCurrentPage();
	}
	
	/**
	 * goes to the previous page and transitions the pictures
	 */
	private void previousPage() {
		currentPage--;
		if(currentPage <= 0) {
			currentPage = 0;
			prev.setEnabled(false);
		}
		else if(!next.isEnabled()) {
			next.setEnabled(true);
		}
		else if(!prev.isEnabled()) {
			prev.setEnabled(true);
		}
		populatePage();
		initViews();
		displayCurrentPage();
	}
	
	/**
	 * fills in the views with the pictures that are supposed to be
	 * on this page
	 */
	private void populatePage() {
		Vector<String> newPics = new Vector<String>();
		for(int i = (currentPage * PICS_PER_PAGE); 
				i < (currentPage * PICS_PER_PAGE) + PICS_PER_PAGE; 
				i++) {
			
					if(i >= pictures.size())
						i = pictures.size() - 1;
					
					newPics.add(pictures.elementAt(i));
				}
		curPage = new Page(newPics.toArray(new String[newPics.size()]));
	}
	
	/**
	 * displays the current page
	 */
	private void displayCurrentPage() {
		pDia.show();
		new LoadImageTask().execute();
	}
	
	/**
	 * Initializes the current page
	 */
	private void initPage() {
		if(!init) {
			init = true;
			if(pictures.size() % PICS_PER_PAGE == 0)
				numPages = pictures.size() / PICS_PER_PAGE;
			else
				numPages = (pictures.size() / PICS_PER_PAGE) + 1;
			
			
			//setup pages
			//less than 2 pages
			if(pictures.size() != 0) {
				if(pictures.size() <= PICS_PER_PAGE) {
					String[] curPagePics = pictures.toArray(new String[pictures.size()]);
					curPage = new Page(curPagePics);
					prev.setEnabled(false);
					next.setEnabled(false);
				}
				else if(pictures.size() <= PICS_PER_PAGE * 2) {
					String[] curPagePics = pictures.subList(currentPage * PICS_PER_PAGE, currentPage * PICS_PER_PAGE + PICS_PER_PAGE).toArray(new String[6]);
					curPage = new Page(curPagePics);
					prev.setEnabled(false);
				}
				else {
					String[] curPagePics = pictures.subList(currentPage * PICS_PER_PAGE, currentPage * PICS_PER_PAGE + PICS_PER_PAGE).toArray(new String[6]);
					curPage = new Page(curPagePics);
				}
				initViews();
				displayCurrentPage();
			}
			else {
				Log.e(TAG, "No pictures found on SD card!");
				finish();
			}
		}
	}
	
	/**
	 * Initializes the views on the page to clear them out
	 */
	private void initViews() {
		for(int i = 0; i < IMAGE_IDS.length; i++) {
			FlickImageView v = (FlickImageView) findViewById(IMAGE_IDS[i]);
			Drawable d = v.getDrawable();
			if(d != null) {
				Bitmap bm = ((BitmapDrawable)d).getBitmap();
				if(bm != null && !bm.isRecycled())
					bm.recycle();
				d = null;
				bm = null;
				v.setImageBitmap(null);
				v.setImageDrawable(null);
				v.setVisibility(ImageView.INVISIBLE);
			}
			v.setPath("");
		}
	}
	
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data){
		if(requestCode == PHOTO_REQUEST) {
			if(resultCode == Activity.RESULT_OK) {
				String result = data.getStringExtra(PhotoManager.RESULT);
				String picPath = data.getStringExtra(PhotoManager.PICTURE);
				
				//picture was deleted
				if(result.equals(PhotoManager.DELETE)) {
					if(pictures.remove(picPath))
						initPage();
				}
			}
		}
	}
	
	private class LoadImageTask extends AsyncTask <Void, Void, Void> {
		@Override
		protected Void doInBackground(Void... params) {
			curPage.loadPictures();
			return null;
		}
		
		@Override
		protected void onPostExecute(Void result) {
			pDia.dismiss();
			
			//create rows
			int rows = 0;
			if(curPage.numPics() % 2 == 0)
				rows = curPage.numPics() / 2;
			else
				rows = (curPage.numPics() / 2) + 1;
			int j = 0;
			for(int i = 0; i < rows; i++) {
				FlickImageView view1 = (FlickImageView) findViewById(IMAGE_IDS[j]);
				view1.setImageBitmap(curPage.getPicture(j));
				view1.setPath(curPage.getPaths()[j]);
				view1.setVisibility(ImageView.VISIBLE);
				view1.setOnClickListener(new OnClickListener() {
					@Override
					public void onClick(View v) {
						FlickImageView v2 = (FlickImageView) v;
						
						if(!v2.isBlank()) {
							Intent photoIntent = new Intent(getApplicationContext(), PhotoManager.class);
							photoIntent.putExtra("path", v2.getPath());
							photoIntent.putExtra("saved", true);
							
							init = false;
							startActivityForResult(photoIntent, PHOTO_REQUEST);
						}
					}
				});
				j++;
				if(j >= curPage.numPics()) {
					break;
				}
				
				FlickImageView view2 = (FlickImageView) findViewById(IMAGE_IDS[j]);
				view2.setImageBitmap(curPage.getPicture(j));
				view2.setPath(curPage.getPaths()[j]);
				view2.setVisibility(ImageView.VISIBLE);
				view2.setOnClickListener(new OnClickListener() {
					@Override
					public void onClick(View v) {
						FlickImageView v2 = (FlickImageView) v;
						if(!v2.isBlank()) {
							Intent photoIntent = new Intent(getApplicationContext(), PhotoManager.class);
							photoIntent.putExtra("path", v2.getPath());
							photoIntent.putExtra("saved", true);
			
							init = false;
							startActivityForResult(photoIntent, PHOTO_REQUEST);
						}
					}
				});
				j++;
			}
		}
		
	}
	
}